package util;

import observer.Copiable;

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

/**
 * This is a class of clipboard utility functions.
 *
 * @author Neil Dickson
 */
public final class ClipboardUtil {
	/**
	 * This IS the clipboard for objects, since Java's version of it needs things to be {@link java.io.Serializable}, defeating the purpose of a local VM transfer.
	 */
	private static Copiable	copiedObject = null;

	/**
	 * @return any text on the clipboard, or null if none
	 */
	public static String getClipboardText() {
		Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
		try {
			if (t!=null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
				return (String)t.getTransferData(DataFlavor.stringFlavor);
			}
		}
		catch (UnsupportedFlavorException e) {}
		catch (IOException e) {}
		return null;
	}

	/**
	 * Sets the clipboard to contain text
	 * @param text the text to put on the clipboard
	 */
	public static void setClipboardText(String text) {
		copiedObject = null;
		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text),null);
	}

	/**
	 * Finds and copies a Java object on the clipboard.
	 * @return a copy of the Java object on the clipboard (i.e. a copy of a copy of the original object)
	 */
	public static Object getClipboardJavaObject() {
		// NOTE: Java's object clipboard is terrible, so I've done it the simple way instead.
		if (getClipboardText()!=null) {
			copiedObject = null;
		}
		return copiedObject!=null ? copiedObject.copy() : null;
//		Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
//		try {
//			if (t!=null) {
//				DataFlavor[] flavours = t.getTransferDataFlavors();
//				for (DataFlavor flavour : flavours) {
//					if (flavour.getPrimaryType().equals(DataFlavor.javaJVMLocalObjectMimeType) || flavour.getSubType().equals(DataFlavor.javaJVMLocalObjectMimeType)) {
//						return ((observer.Copiable)t.getTransferData(flavour)).copy();
//					}
//				}
//			}
//		}
//		catch (UnsupportedFlavorException e) {}
//		catch (IOException e) {}
//		return null;
	}

	/**
	 * Puts a copy of the specified object onto the clipboard.
	 * @param object the object whose copy is to go on the clipboard
	 */
	public static void setClipboardJavaObject(final Copiable<? extends Copiable> object) {
		// NOTE: Java's object clipboard is terrible, so I've done it the simple way instead.
		// Clear the text clipboard before adding something to the Java object one.
		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(null),null);
		copiedObject = object.copy();
//		DataFlavor flavour = null;
//		try {
//			flavour = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+";class=\""+object.getClass().getName()+"\"");
//		}
//		catch (ClassNotFoundException e) {
//			// This can never happen, because the class is always loaded before the object is created.
//		}
//		final DataFlavor objectFlavour = flavour;
//		final observer.Copiable duplicate = object.copy();
//		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new Transferable(){
//			public DataFlavor[] getTransferDataFlavors() {
//				if (objectFlavour!=null) {
//					return new DataFlavor[]{objectFlavour};
//				}
//				return new DataFlavor[0];
//			}
//			public boolean isDataFlavorSupported(DataFlavor flavour) {
//				return flavour==objectFlavour;
//			}
//			public observer.Copiable getTransferData(DataFlavor flavour) throws UnsupportedFlavorException, IOException {
//				if (flavour==objectFlavour) {
//					return duplicate;
//				}
//				throw new UnsupportedFlavorException(flavour);
//			}
//		},null);
	}
}
